﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using MyCadDll;

namespace XhPaper
{
    public class JdqJieDianClass
    {
        public CadText jieDianName;
        public CadText jieDianText;
        //public double[] nameZuoBiao;
        //public double[] textZuobiao;      
        public JdqJieDianClass()
        {
            jieDianName = new CadText();
            jieDianText = new CadText();
        }
    }
    public class jdqOtherPropertyClass
    {
        public string name;
        public double[] nameZuoBiao;
    }
   
    public class JiDianQiClass:GetPointInterface
    {
       // string strcfg;
        /// <summary>
        /// 文字相对于表格x轴的偏移量
        /// </summary>
        double textDx=0.5;
        /// <summary>
        /// 文字相对于表格y轴的偏移量
        /// </summary>
        double textDy=0.5;
        /// <summary>
        /// 两个继电器图形间x轴方向的间距
        /// </summary>
        double offsetX=10;
        /// <summary>
        /// 两个继电器图形间y轴方向的间距
        /// </summary>
        double offsetY=10;
        /// <summary>
        /// 继电器图形在cad中x轴的位置。从0开始。
        /// </summary>
        int nx;
        /// <summary>
        /// 继电器图形在cad中y轴的位置。从0开始。
        /// </summary>
        int ny;
        double left;
        double bottom;
        /// <summary>
        /// 继电器图形的宽度
        /// </summary>
        double width;
        /// <summary>
        /// 继电器图形的高度
        /// </summary>
        double height;
        /// <summary>
        /// 继电器接点编号
        /// </summary>
        int[] jieDianNo = new int[] {1,2,3,4,13,23,11,21,12,22,33,43,31,41,32,42,53,63,51,61,52,62,73,83,71,81,72,82 };
        /// <summary>
        /// 继电器其他文字的数组
        /// </summary>
        string[] othername = new string[] {"位置板号","型号","名称" };
        /// <summary>
        /// 继电器接点类字典
        /// </summary>
        Dictionary<string, JdqJieDianClass> jdJieDianDic;
        /// <summary>
        /// 继电器其他属性字典
        /// </summary>
        Dictionary<string, jdqOtherPropertyClass> jdOtherPropertyDic;
        /// <summary>
        /// 继电器结构
        /// </summary>
        StructClass jdqStruct;
        XmlDocument xmlDoc;
        /// <summary>
        /// 完成对cad的各种操作
        /// </summary>
        MyCadDllClass myCadDll;
        public JiDianQiClass(int hang,int lie)
        {
            nx = lie;
            ny = hang;
            xmlDoc = new XmlDocument();
            string filename = System.IO.Directory.GetCurrentDirectory()+"\\jdqXMLFile1.xml";
            xmlDoc.Load(filename);
            myCadDll = new MyCadDllClass();
            jdJieDianDic = new Dictionary<string, JdqJieDianClass>();
            jdOtherPropertyDic = new Dictionary<string, jdqOtherPropertyClass>();
            CreateJdqStruct();
            CreatejdqJieDian();
        }
        /// <summary>
        /// 创建继电器的图形结构，该图形结构为各种线段组成。该函数就是生成这些线段的列表
        /// </summary>
        private void CreateJdqStruct()
        {
            if (jdqStruct == null)
            {
                jdqStruct = new StructClass();
                XmlElement root = xmlDoc.DocumentElement;
                #region 得到矩形坐标
                double bottom, left, width, heigh;
                XmlNodeList nodeList = root.SelectNodes("RECT");
                if (nodeList.Count > 0)
                {
                    double.TryParse(nodeList.Item(0).Attributes["Bottom"].Value, out bottom);
                    double.TryParse(nodeList.Item(0).Attributes["Left"].Value, out left);
                    double.TryParse(nodeList.Item(0).Attributes["WIDTH"].Value, out width);
                    double.TryParse(nodeList.Item(0).Attributes["HEIGHT"].Value, out heigh);
                    this.left = left;
                    this.bottom = bottom;
                    this.width = width;
                    this.height = heigh;
                    jdqStruct.AddxLine(0, new double[] {left ,bottom  ,0 }, new double[] {left,bottom+heigh,0 });
                    jdqStruct.AddxLine(5, new double[] {left+width,bottom,0 }, new double[] {left+width,bottom+heigh,0 });
                    jdqStruct.AddyLine(0, new double[] {left,bottom,0 }, new double[] {left+width,bottom,0 });
                    jdqStruct.AddyLine(16, new double[] {left,bottom+heigh,0 }, new double[] {left+width,bottom+heigh,0 });
                }
                #endregion
                #region 得到行坐标
                double JianGe, StartX, EndX;
                int Count;
                XmlNodeList nodeList1 = root.SelectNodes("JieDianHang");
                if (nodeList1.Count > 0)
                {
                    double.TryParse(nodeList1.Item(0).Attributes["JianGeY"].Value, out JianGe);
                    double.TryParse(nodeList1.Item(0).Attributes["StartX"].Value, out StartX);
                    double.TryParse(nodeList1.Item(0).Attributes["EndX"].Value, out EndX);
                    int.TryParse(nodeList1.Item(0).Attributes["Count"].Value, out Count);
                    double[] points1 , points2 ;
                    for (int i = 0; i < Count; i++)
                    {
                        points1 = new double[] { StartX, JianGe * (i + 1), 0 };
                        points2 = new double[] { EndX, JianGe * (i + 1), 0 };
                        jdqStruct.AddyLine(i + 1, points1, points2);
                    }
                }
                #endregion
                #region 得到列坐标
                double StartY, EndY;
                double[] lX = new double[3];
                XmlNodeList nodeList2 = root.SelectNodes("JieDianLie");
                if (nodeList1.Count > 0)
                {
                    double.TryParse(nodeList2.Item(0).Attributes["X1"].Value, out lX[0]);
                    double.TryParse(nodeList2.Item(0).Attributes["X2"].Value, out lX[1]);
                    double.TryParse(nodeList2.Item(0).Attributes["X3"].Value, out lX[2]);
                    double.TryParse(nodeList2.Item(0).Attributes["StartY"].Value, out StartY);
                    double.TryParse(nodeList2.Item(0).Attributes["EndY"].Value, out EndY);
                    double[] points1 , points2 ;
                    int j=0;
                    for (int i = 0; i < 3; i++)
                    {
                        points1 = new double[] { lX[i], StartY, 0 };
                        points2 = new double[] { lX[i], EndY, 0 };
                        if (++j == 2)
                        {
                            j++;
                        }
                        jdqStruct.AddxLine(j, points1, points2);
                    }
                }
                #endregion
                #region 得到其他坐标
                XmlNodeList nodeList3 = root.SelectNodes("QiTa");
                string strlinex1, strliney2;
                if (nodeList1.Count > 0)
                {
                    strlinex1 = nodeList3.Item(0).Attributes["linex1"].Value;
                    strliney2 = nodeList3.Item(0).Attributes["liney2"].Value;
                    double[] points1 , points2 ;
                    double[] d =MyCommonMethod.GetDoubles(strlinex1);
                    points1 = new double[] { d[0], d[1], 0 };
                    points2 = new double[] { d[2], d[3], 0 };
                    jdqStruct.AddxLine(2, points1, points2);
                    d = MyCommonMethod.GetDoubles(strliney2);
                    points1 = new double[] { d[0], d[1], 0 };
                    points2 = new double[] { d[2], d[3], 0 };
                    jdqStruct.AddyLine(15, points1, points2);   
                }
                #endregion
            }
        }
        /// <summary>
        /// 每个接点包括该接点的名称、文字及他们对应的坐标。该函数功能就是生产接点字典
        /// </summary>
        private void CreatejdqJieDian()
        {
            for (int i = 0; i < jieDianNo.Length; i++)
            {
                JdqJieDianClass jdclass = new JdqJieDianClass();
                jdclass.jieDianName.m_text = jieDianNo[i].ToString();
                jdclass.jieDianName.m_coordinate = GetjdNameZuoBiao(i);
                jdclass.jieDianText.m_coordinate = GetjdTextZuoBiao(i);
                jdJieDianDic.Add(jdclass.jieDianName.m_text, jdclass);
            }
        }
        /// <summary>
        /// 得到对应序号接点名称的坐标
        /// </summary>
        /// <param name="i">接点的序号，不是接点名称</param>
        /// <returns></returns>
        private double[] GetjdNameZuoBiao(int i)
        {
            int iy, ix;
            if (jdqStruct == null)
            {
                CreateJdqStruct();
            }
            iy = i / 2;
            ix = i % 2 == 0 ? 0 : 3;
            XhGraphicLine liney1 = jdqStruct.yLineDic[iy];
            XhGraphicLine liney2 = jdqStruct.yLineDic[iy + 1];
            XhGraphicLine linex1 = jdqStruct.xLineDic[ix];
            XhGraphicLine linex2 = jdqStruct.xLineDic[ix + 1];
            double[] d = new double[] { linex1.startP[0]+textDx, liney1.startP[1]+textDy, 0 ,linex1.startP[0]+textDx,liney2.startP[1]-textDy,0,
                                        linex2.startP[0]-textDx, liney2.startP[1]-textDy, 0 ,linex2.startP[0]-textDx,liney1.startP[1]+textDy, 0 };
            return d;
        }
        /// <summary>
        /// 得到对应序号接点文字的坐标
        /// </summary>
        /// <param name="i">接点的序号，不是接点名称</param>
        /// <returns></returns>
        private double[] GetjdTextZuoBiao(int i)
        {
            int iy, ix;
            if (jdqStruct == null)
            {
                CreateJdqStruct();
            }
            iy = i / 2;
            ix = i % 2 == 1 ? 1 : 4;
            XhGraphicLine liney1 = jdqStruct.yLineDic[iy];
            XhGraphicLine liney2 = jdqStruct.yLineDic[iy+1];
            XhGraphicLine linex1 = jdqStruct.xLineDic[ix];
            XhGraphicLine linex2 = jdqStruct.xLineDic[ix+1];
            double[] d = new double[] { linex1.startP[0]+textDx, liney1.startP[1]+textDy, 0 ,linex1.startP[0]+textDx,liney2.startP[1]-textDy,0,
                                        linex2.startP[0]-textDx, liney2.startP[1]-textDy, 0 ,linex2.startP[0]-textDx,liney1.startP[1]+textDy, 0 };
            return d;
        }
        /// <summary>
        /// 创建继电器其他属性的字典
        /// </summary>
        private void CreatejdqOtherProperty()
        {
            for (int i = 0; i < othername.Length; i++)
            {
                jdqOtherPropertyClass jdOtherclass = new jdqOtherPropertyClass();
                jdOtherclass.name = othername[i];
                jdOtherclass.nameZuoBiao = GetjdOtherZuoBiao(i);

                jdOtherPropertyDic.Add(jdOtherclass.name, jdOtherclass);
            }
        }
        /// <summary>
        /// 得到其他几点属性的坐标
        /// </summary>
        /// <param name="i">继电器其他属性的序号。othername数组的对应下标</param>
        /// <returns></returns>
        private double[] GetjdOtherZuoBiao(int i)
        {
            if (jdqStruct == null)
            {
                CreateJdqStruct();
            }
            double[] d;
            switch (i)
            {
                case 0:
                    d = new double[] {jdqStruct.xLineDic[0].startP[0],jdqStruct.yLineDic[14].startP[1],0,
                                      jdqStruct.xLineDic[0].startP[0],jdqStruct.yLineDic[16].startP[1],0,
                                      jdqStruct.xLineDic[2].startP[0],jdqStruct.yLineDic[16].startP[1],0,
                                      jdqStruct.xLineDic[2].startP[0],jdqStruct.yLineDic[14].startP[1],0
                                     };
                    break;
                case 1:
                    d = new double[] {jdqStruct.xLineDic[2].startP[0],jdqStruct.yLineDic[14].startP[1],0,
                                      jdqStruct.xLineDic[2].startP[0],jdqStruct.yLineDic[15].startP[1],0,
                                      jdqStruct.xLineDic[5].startP[0],jdqStruct.yLineDic[15].startP[1],0,
                                      jdqStruct.xLineDic[5].startP[0],jdqStruct.yLineDic[14].startP[1],0
                                     };
                    break;
                case 2:
                    d = new double[] {jdqStruct.xLineDic[2].startP[0],jdqStruct.yLineDic[15].startP[1],0,
                                      jdqStruct.xLineDic[2].startP[0],jdqStruct.yLineDic[16].startP[1],0,
                                      jdqStruct.xLineDic[5].startP[0],jdqStruct.yLineDic[16].startP[1],0,
                                      jdqStruct.xLineDic[5].startP[0],jdqStruct.yLineDic[15].startP[1],0
                                     };
                    break;
                default:
                    d = new double[] {0,0,0, 0,0,0, 0,0,0, 0,0,0 };
                    break;
            }
            
            return d;
        }
        public void DrawJiDianQi()
        {   
            XmlElement root= xmlDoc.DocumentElement;
            #region 绘制矩形
            double bottom, left, width, heigh; 
            XmlNodeList nodeList = root.SelectNodes("RECT");
            if (nodeList.Count > 0)
            {
                double.TryParse(nodeList.Item(0).Attributes["Bottom"].Value, out bottom);
                double.TryParse(nodeList.Item(0).Attributes["Left"].Value, out left);
                double.TryParse(nodeList.Item(0).Attributes["WIDTH"].Value, out width);
                double.TryParse(nodeList.Item(0).Attributes["HEIGHT"].Value, out heigh);
                myCadDll.DrawRectToCad(GetRectDoubles(bottom,left,width,heigh ),0.5);
            }
            #endregion
            #region 绘制行
            double JianGe, StartX, EndX;
            int Count;
            XmlNodeList nodeList1 = root.SelectNodes("JieDianHang");
            if (nodeList1.Count > 0)
            {
                double.TryParse(nodeList1.Item(0).Attributes["JianGeY"].Value, out JianGe);
                double.TryParse(nodeList1.Item(0).Attributes["StartX"].Value, out StartX);
                double.TryParse(nodeList1.Item(0).Attributes["EndX"].Value, out EndX);
                int.TryParse(nodeList1.Item(0).Attributes["Count"].Value, out Count);
                double[][] points1=new double[Count][], points2=new double[Count][];
                for (int i = 0; i < Count; i++)
                {
                    points1[i] = new double[] {StartX ,JianGe*(i+1),0 };
                    points2[i] = new double[] { EndX, JianGe * (i + 1), 0 };
                }
                myCadDll.DrawLinesToCad(points1, points2, Count);
            }
            #endregion
            #region 绘制列
            double StartY, EndY;
            double[] lX=new double[3];
            XmlNodeList nodeList2 = root.SelectNodes("JieDianLie");
            if (nodeList1.Count > 0)
            {
                double.TryParse(nodeList2.Item(0).Attributes["X1"].Value, out lX[0]);
                double.TryParse(nodeList2.Item(0).Attributes["X2"].Value, out lX[1]);
                double.TryParse(nodeList2.Item(0).Attributes["X3"].Value, out lX[2]);
                double.TryParse(nodeList2.Item(0).Attributes["StartY"].Value, out StartY);
                double.TryParse(nodeList2.Item(0).Attributes["EndY"].Value, out EndY);
                double[][] points1 = new double[3][], points2 = new double[3][];
                for (int i = 0; i < 3; i++)
                {
                    points1[i] = new double[] { lX [i], StartY, 0 };
                    points2[i] = new double[] { lX [i], EndY , 0 };
                }
                myCadDll.DrawLinesToCad(points1, points2, 3);
            }
            #endregion
            #region 绘制其他
              XmlNodeList nodeList3 = root.SelectNodes("QiTa");
              string strline1,strline2;
            if (nodeList1.Count > 0)
            {
                strline1=nodeList3.Item(0).Attributes["linex1"].Value;
                strline2=nodeList3.Item(0).Attributes["liney2"].Value;
                double[][] points1=new double[2][],points2=new double[2][];
                double[] d = MyCommonMethod.GetDoubles(strline1);
                points1[0]=new double[]{d[0],d[1],0};
                points2[0]=new double[]{d[2],d[3],0};
                d = MyCommonMethod.GetDoubles(strline2);
                points1[1] = new double[] { d[0], d[1], 0 };
                points2[1] = new double[] { d[2], d[3], 0 };
                myCadDll.DrawLinesToCad(points1, points2, 2);
            }
            #endregion
        }
        public void DrawJiDianQiStruct()
        {
            #region 绘制列
            int n=jdqStruct.xLineDic.Count;
            if (n > 0)
            {
                for (int i = 0; i < n; i++)
                {
                    myCadDll.DrawLineToCad(GetLineDoubles(jdqStruct.xLineDic[i]),0);
                }
            }
            #endregion
            #region 绘制行
            n = jdqStruct.yLineDic.Count;
            if (n > 0)
            {
                for (int i = 0; i < n ; i++)
                {
                    myCadDll.DrawLineToCad(GetLineDoubles(jdqStruct.yLineDic[i]), 0);
                }
            }
            #endregion
            #region 绘制矩形
            myCadDll.DrawRectToCad(GetRectDoubles(bottom, left, width, height), 0.5);
            #endregion
        }
        public void DrawJiDianQiName()
        {
            JdqJieDianClass jd;
            foreach (int s in jieDianNo)
            {
                jd = jdJieDianDic[s.ToString()];
                DrawJieDianName(jd);
                DrawJieDianText(jd);
            }
        }
        public void DrawJieDianName(JdqJieDianClass jd)
        {
            if(jd.jieDianName !=null)
            myCadDll.DrawTextToCad(GetLeftBottomPoint(jd.jieDianName.m_coordinate), jd.jieDianName.m_text, 1.5);
        }
        public void DrawJieDianText(JdqJieDianClass jd)
        {
            if (jd.jieDianText != null) 
            myCadDll.DrawTextToCad(GetLeftBottomPoint(jd.jieDianText.m_coordinate), jd.jieDianText.m_text, 1.5);
        }
        public void DrawJiDianQiOther()
        {

        }
        /// <summary>
        /// 把矩形的右下角点、长度、宽度按照对应的偏移量，转换为对应的点的数组，这些点是一个闭环的点数组
        /// </summary>
        /// <param name="b1"></param>
        /// <param name="l1"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        /// <returns></returns>
        private double[] GetRectDoubles(double b1, double l1, double w, double h)
        {
            double l, b;
            l = AdjustX(l1);
            b = AdjustY(b1);
            double[] d = new double[] { l, b, 0, l + w, b, 0, l + w, b + h, 0, l, b + h, 0, l, b, 0 };
            return d;
        }
        private double[] GetLineDoubles(XhGraphicLine line)
        {
            double[] d=new double[]{AdjustX(line.startP[0]),AdjustY(line.startP[1]),0,
                                    AdjustX(line.endP[0]),AdjustY(line.endP[1]),0
                                    };
            return d;
        }
        /// <summary>
        /// 把参数d数值按照x轴方向的偏移量进行调整
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private double AdjustX(double d)
        {
            double d1 = d + nx * (offsetX + width);
            return d1;
        }
        /// <summary>
        /// 把参数d数值按照y轴方向的偏移量进行调整
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        private double AdjustY(double d)
        {
            double d1 = d + ny * (offsetY + height);
            return d1;
        }
        /// <summary>
        /// 把有数字组成的字符串，转换为double 数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        //private double[] GetDoubles(string s)
        //{
        //    char[] ch=new char[]{','};
        //    double[] d;
        //    string[] str= s.Split(ch, StringSplitOptions.RemoveEmptyEntries);
        //    d = new double[str.Length];
        //    for (int i = 0; i < str.Length; i++)
        //    {
        //        double.TryParse(str[i], out d[i]);
        //    }
        //    return d;
        //}
        #region 接口实现
        public double[] GetLeftBottomPoint(double[] d)
        {
            if (d.Length > 3)
            {
                return new double[] { AdjustX(d[0]), AdjustY(d[1]), d[2] };
            }
            else
            {
                return new double[] {0,0,0 };
            }
        }

        public double[] GetLeftTopPoint(double[] d)
        {
            if (d.Length > 6)
            {
                return new double[] { AdjustX(d[3]), AdjustY(d[4]), d[5] };
            }
            else
            {
                return new double[] { 0, 0, 0 };
            }
        }

        public double[] GetRightTopPoint(double[] d)
        {
            if (d.Length > 9)
            {
                return new double[] { AdjustX(d[6]), AdjustY(d[7]), d[8] };
            }
            else
            {
                return new double[] { 0, 0, 0 };
            }
        }

        public double[] GetRightBottomPoint(double[] d)
        {
            if (d.Length > 12)
            {
                return new double[] { AdjustX(d[9]), AdjustY(d[10]), d[11] };
            }
            else
            {
                return new double[] { 0, 0, 0 };
            }
        }
        #endregion
    }
}
